/**
 * @name RestJs组件{Higsoft软件体系服务资源请求JSSDK}
 * @author wangsongle
 * @description 2021/10/26
 * @copyright http://songle.wang
 * @version 1.0
 */
import axios from 'axios'
import store from '../store/index'
import {MD5} from '../libs/md5'
import base_config from '../config/config'
import ViewUI from 'view-design'
/**
 * 自定义全局axios实例
 */
const request = axios.create({
	baseURL: env_config.base_url
})

//创建请求撤消对象
const CancelToken = axios.CancelToken;
let cancel;

request.interceptors.request.use(function(config){
	//开启撤消请求
	config.cancelToken = new CancelToken(function executor(c) {
		// An executor function receives a cancel function as a parameter
		cancel = c;
	})
	let loading = config.loading || base_config.show_loading;
	if(loading){
		ViewUI.LoadingBar.start();
	}
	config.headers.Authorization = 'Bearer '+store.getToken();
	return config;
},function(error){
	return Promise.reject(error);
})
request.interceptors.response.use(function (response){
	//加载结束
	ViewUI.LoadingBar.finish();
	if(response.data){
		if(response.data.code === 40001 || response.data.code === 401){
			if(localStorage.getItem('refresh_token') === 'undefined') {
				store.login()
			}
			new RestDao({
				gateway: 'agrobiz',
				service: "agrobiz-uc",
				url: "/v1.0/open-src/admin/refresh",
				action: (res)=>{
					if (res.data.code === 20000) {
						store.initUser(res.data.data)
						console.log(response.config,'response.config')
						request(response.config).then((response) => {
							if (response != null && response.config.action) {
								response.config.action(response);
							}
						}).catch((error) => {
							console.error("error ->",error+"")
							ViewUI.Notice.warning({
								title: '请求异常',
								desc: `原因：${error+""}`
							})
						})
					} else {
						store.login()
					}
				}
			}).refresh(localStorage.getItem('refresh_token'))
		} else {
			return response;
		}
	} else {
		ViewUI.Message.error(response.status);
		console.error(response.status);
		return null;
	}
}, function(error){
	return Promise.reject(error);
})

/**
 *
 * @param {查询类} options 请求参数
 */
class RestDao {
  constructor(options) {
		this.gateway = options.gateway
		this.service = options.service
		this.base = options.base
		this.url = options.url
		this.query = options.query || {}
		this.data = options.data
		this.action = options.action
		this.form = options.form
		this.loading = options.loading
		this.error = options.error
		this.api = null
		this.apiHeader = {}
  }

  /**
   * 获取资源请求
   */
  get(blank = false) {
		//检查请求参数
		this.checkRequest()

		/**
		 * 在刷新浏览器的情况下，store缓存被清除，access_token重新初始化
		 * 需要把数据请求方法注入到sessionReadyCallback的回调中
		 */
		/* if (store.getToken() == null) {
			store.setSessionReadyCallback(()=>{
				new RestDao({
					gateway: this.gateway,
					service: this.service,
					url: this.url,
					base: this.base,
					query: this.query,
					loading: this.loading,
					error: this.error,
					action: this.action
				}).get()
			})
			return false
		} */

		//处理请求参数
		this.getRestHandle(blank)


		request.get(this.api, {
			service: this.service,
			params: {query:this.query},
			loading: this.loading,
			headers: this.apiHeader,
			action: this.action
		}).then((response) => {
			if (response != null && this.action) {
				this.action(response);
			}
		}).catch((error) => {
			if(this.error) {
				this.error(error.toString())
			} else {
				ViewUI.Notice.warning({
					title: '请求异常',
					desc: `异常原因：${error.toString()}`
				})
			}
		})
  }

  /**
   * 创建资源
   * @param {是否判空} blank 
   * @param {请求方法} method 
   */
  post(blank = false, method = 'post') {
		//检查请求参数
		this.checkRequest()

		//处理请求参数
		this.postRestHandle(blank)

		request({
			service: this.service,
			url: this.api,
			data: this.data || this.form,
			method: method,
			loading: this.loading,
			headers: this.apiHeader,
			action: this.action
		}).then((response) => {
			if (response != null && this.action) {
				this.action(response);
			}
		}).catch((error) => {
			console.error("post ->",error+"")
			if(this.error) {
				this.error(error+"")
			} else {
				ViewUI.Notice.warning({
					title: '请求异常',
					desc: `异常原因：${error+""}`
				})
			}
		})
  }

  /**
   * 更新资源
   * @param {是否判空} blank 
   */
  put(blank = false) {
		this.post(blank,'put')
  }

  /**
   * 删除资源
   * @param {是否判空} blank 
   */
  delete(blank = false) {
		this.post(blank,'delete')
  }

  refresh(token) {
		this.apiHeader["RefreshToken"] = token
		this.get(false)
  }

  /**
   * 返回结果Promise
   */
  call(blank = false) {
		//校验请求参数
		this.checkRequest()

		//处理请求参数
		this.getRestHandle(blank)

		request.get(this.api, {
			service: this.service,
			params: {query:this.query},
			loading: this.loading,
			headers: this.apiHeader
		})
  }

  /**
   * 上传文件
   */
  upload(){
		if(!this.form){
			this.error ? this.error('missing form') : ViewUI.Message.warning('missing form')
			return false;
		}
		if(!this.form.binaryFile){
			this.error ? this.error('missing binaryFile') : ViewUI.Message.warning('missing binaryFile')
			return false;
		}

		//检查请求地址
		this.checkRequest()

		//处理请求参数
		this.apiHeader["Content-Type"] = 'multipart/form-data'
		this.form = this.jsonToFormData(this.form)

		request({
			service: this.service,
			url: this.api,
			data: this.form,
			method: 'post',
			loading: this.loading,
			headers: this.apiHeader
		}).then((response) => {
			if (response != null && this.action) {
				this.action(response);
			}
		}).catch((error) => {
			console.error("upload ->",error+"")
			if(this.error) {
				this.error(error+"")
			} else {
				ViewUI.Notice.warning({
					title: '请求异常',
					desc: `异常原因：${error+""}`
				})
			}
		})
  }

  checkRequest(){
		if (!this.service || this.service === ' ') {
			this.error ? this.error('missing service') : ViewUI.Message.warning('missing service')
					return false;
			}
			if (!this.url || this.url === ' ') {
			this.error ? this.error('missing url') : ViewUI.Message.warning('missing url')
					return false;
			}
		if (this.url.indexOf('/'+this.service) === 0) {
			this.url = this.url.replace('/'+this.service,'')
		}
		if (env_config.debug) {
			this.api = base_config.local_url[this.gateway] + '/' + this.gateway + '/' + this.service + this.url
		} else {
			this.api = '/' + this.gateway + '/' + this.service + this.url
		}
  }

  getRestHandle(blank){
		if(blank && !this.isNotBlank(this.query)) {
			this.error ? this.error('请求参数不完整') : ViewUI.Message.warning('请求参数不完整')
			return false
		}
		this.deleteEmptyProperty(this.query);
		// this.query.appCode = store.getUser('appCode')
		//时间戳-秒精
		
		let timestamp = Date.parse(new Date()).toString();
		if(store.getSession()){
			this.query.apiUri = this.url;
			this.query.timestamp = timestamp;
			let body = this.jsonSort(this.query);
			this.query = body;
			console.log('query: ',JSON.stringify(body));
			this.apiHeader["Timestamp"] = timestamp;
			this.apiHeader["Sign"] = MD5(store.getSession() + /* this.url + */ JSON.stringify(body)).toUpperCase();
			console.log('sign: ',this.apiHeader["Sign"]);
		}
  }

  postRestHandle(blank){
		if (blank && !this.isNotBlank(this.data || this.form)) {
			this.error ? this.error('请填写完整') : ViewUI.Message.warning('请填写完整')
			return false
		}

		this.deleteEmptyProperty(this.data || this.form);

		if (this.form && typeof this.form === 'object') {
			this.apiHeader["Content-Type"] = 'application/x-www-form-urlencoded;charset=UTF-8'
			this.form = this.jsonToFormData(this.form)
		} else if(this.data && typeof this.data === 'object') {
			this.apiHeader["Content-Type"] = 'application/json;charset=UTF-8'
			this.data.timestamp = Date.parse(new Date()).toString();
			this.data.apiUri = this.url;
			let body = this.jsonSort(this.data);
			console.log('body: ',JSON.stringify(body));
			this.apiHeader["Timestamp"] = this.data.timestamp;
			this.apiHeader["Sign"] = MD5(store.getSession() + JSON.stringify(body)).toUpperCase();
			console.log('sign: ',this.apiHeader["Sign"]);
		} else {
			this.error ? this.error('missing data') : ViewUI.Message.warning('missing data')
			return false;
		}
  }

  /**
   * 自然排序
   * @param {Json请求对象} jsonObj 
   */
  jsonSort(jsonObj){
		let array = new Array();
		let newJson = {};
		for(let key in jsonObj){
			let value = jsonObj[key];
			if (typeof value === 'object') {
				if (Array.isArray(value)) {
					if (value.length > 0) {
						value.forEach((item,id)=>{
							if (typeof item === 'object') {
								value[id] = this.jsonSort(item)
							}
						})
						value.sort();
						jsonObj[key] = value;
					}
				} else {
					jsonObj[key] = this.jsonSort(value);
				}
			}
			array.push(key)
		}
		array.sort();
		for(let i in array){
			newJson[array[i]] = jsonObj[array[i]]
		}
		return newJson;
  }

  /**
   * 对象数据清理
   * @param {请求对象} object 
   */
  deleteEmptyProperty(object){
		if (typeof object === 'object') {
			for (let i in object) {
				let value = object[i];
				if(this.checkDate(value)){
					object[i] = new Date(value).getTime()
					continue;
				}
				if (typeof value === 'object') {
					if (Array.isArray(value)) {
						if (value.length === 0) {
							delete object[i];
							console.warn('delete Array', i);
							continue;
						} else {
							for (let m=0; m<value.length; m++) {
								this.deleteEmptyProperty(value[m]);
							}
						}
					} else {
						if (this.isEmpty(value)) {
							delete object[i];
							console.warn('delete object', i);
							continue;
						}
						this.deleteEmptyProperty(value);
					}
				} else {
					if(!value && value !== false && value !== 0){
						delete object[i];
						console.warn('delete attribute', i);
						continue;
					}
				}
			}
		}
  }

  /**
   * 请求数据判空
   * @param {Json请求对象} object 
   */
  isNotBlank(object){
		let bool = true;
		for (var i in object) {
			if(!bool){
				break;
			}
			var value = object[i];
			if (value && typeof value === 'object') {
				if (Array.isArray(value)) {
					if (value.length === 0) {
						console.warn('blank array:', i);
						bool = false;
						break;
					}
				} else {
					if (this.isEmpty(value)) {
						console.warn('blank object:', i);
						bool = false;
						break;
					}
				}
				bool = this.isNotBlank(value)
			} else {
				if (value !== false && !value && value !== 0 || value === ' ') {
					console.warn('blank attribute:', i);
					bool = false;
					break;
				}
			}
		}
		return bool
  }

  /**
   * 数据格式转换
   * @param {请求对象} object 
   */
  jsonToFormData(object){
		const formData = new FormData();
		/*JSON转formData*/
		Object.keys(object).forEach((key)=>{
			if(object[key] != null){
				formData.append(key, object[key])
			}
		})
		return formData;
  }

  /**
   * 日期转换
   * @param {日期} date
   */
  checkDate(date){
		var a = /^(\d{4})-(\d{2})-(\d{2})$/
		var b = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/
		var c = /^(\d{4})\/(\d{2})\/(\d{2})$/
		return date instanceof Date || a.test(date) || b.test(date) || c.test(date)
  }

  /**
   * 对象属性判空
   * @param {请求对象} object 
   */
  isEmpty(object){
    for (var name in object){
        return false;
    }
    return true;
  }
}

export const Rest = RestDao;